# -*- coding:utf-8 -*-
# @FileName : app\__init__.py
# @Time     : 2025/11/28
# @Author   : 天空之城
"""应用工厂函数模块

此模块包含Flask应用的工厂函数create_app，用于创建和配置Flask应用实例。
"""
import os
import base64

from flask import Flask
from app.extensions import register_extensions, db
from app.api import register_blueprints
from app.config import DATABASE_URL, SECRET_KEY, JWT_SECRET_KEY, JWT_ACCESS_TOKEN_EXPIRES, DEBUG, TESTING


def create_app(config_name=None):
    """创建Flask应用实例

    Args:
        config_name: 配置名称（如'development'、'production'等）

    Returns:
        Flask应用实例
    """
    app = Flask(__name__)

    # 配置应用
    configure_app(app, config_name)

    # 确保所需目录存在
    ensure_directories_exist()

    # 注册扩展
    register_extensions(app)

    # 初始化数据库（如果不存在则创建）
    init_database(app)

    # 注册蓝图
    register_blueprints(app)

    return app


def ensure_directories_exist():
    """确保应用所需的目录存在

    在应用启动时创建必要的目录，包括数据目录和数据库目录。

    Raises:
        OSError: 如果创建目录失败
    """
    from app.config import DATA_PATH
    for path in (DATA_PATH, os.path.join(DATA_PATH, "database")):
        os.makedirs(path, exist_ok=True)


def configure_app(app, config_name):
    """配置Flask应用

    Args:
        app: Flask应用实例
        config_name: 配置名称
    """
    # 加载默认配置
    app.config['SECRET_KEY'] = 'your-secret-key-here'

    # 数据库配置
    app.config['SQLALCHEMY_DATABASE_URI'] = DATABASE_URL  # 使用SQLite数据库
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

    # JWT配置
    app.config['JWT_SECRET_KEY'] = 'jwt-secret-key-here'
    app.config['JWT_ACCESS_TOKEN_EXPIRES'] = 36000  # 1小时过期

    # 加载配置文件中的配置
    app.config['SECRET_KEY'] = SECRET_KEY
    app.config['JWT_SECRET_KEY'] = JWT_SECRET_KEY
    app.config['JWT_ACCESS_TOKEN_EXPIRES'] = JWT_ACCESS_TOKEN_EXPIRES
    app.config['DEBUG'] = DEBUG
    app.config['TESTING'] = TESTING

    # 根据config_name加载不同的配置
    if config_name == 'development':
        app.config['DEBUG'] = True
    elif config_name == 'production':
        app.config['DEBUG'] = False


def init_database(app):
    """初始化数据库
    
    检测数据库文件是否存在，如果不存在则创建数据库并初始化默认用户。
    
    Args:
        app: Flask应用实例
    """
    from app.models import User, Role, Permission, Conversation, Message, TaskExecution, TaskStep
    from app.config import DATA_PATH
    
    # 数据库文件路径
    db_path = os.path.join(DATA_PATH, 'database', 'app.db')
    
    # 检查数据库文件是否存在
    if not os.path.exists(db_path):
        app.logger.info('数据库文件不存在，开始初始化数据库...')
        
        # 创建所有数据库表
        with app.app_context():
            try:
                # 创建所有表
                db.create_all()
                app.logger.info('数据库表创建成功')
                
                # 创建默认角色
                super_admin_role = Role(
                    name='超级管理员',
                    description='系统超级管理员，拥有所有权限'
                )
                test_user_role = Role(
                    name='测试人员',
                    description='测试用户角色'
                )
                
                db.session.add(super_admin_role)
                db.session.add(test_user_role)
                db.session.commit()
                app.logger.info('默认角色创建成功')
                
                # 创建默认权限
                permissions = [
                    Permission(name='admin_all', description='所有管理员权限'),
                    Permission(name='test_access', description='测试访问权限'),
                    Permission(name='view_conversations', description='查看对话记录'),
                    Permission(name='manage_users', description='管理用户'),
                    Permission(name='manage_models', description='管理模型')
                ]
                
                for permission in permissions:
                    db.session.add(permission)
                db.session.commit()
                app.logger.info('默认权限创建成功')
                
                # 为超级管理员角色分配所有权限
                super_admin_role.permissions.extend(permissions)
                db.session.commit()
                
                # 为测试人员角色分配测试权限
                test_user_role.permissions.append(permissions[1])  # test_access
                db.session.commit()
                app.logger.info('权限分配完成')
                
                # 创建超级管理员用户（email字段可以为空）
                admin_user = User(
                    username='surpriseadmin',
                    email=None  # email字段允许为空
                )
                admin_user.password = 'a*73@1kL98'  # 设置密码
                admin_user.roles.append(super_admin_role)
                
                db.session.add(admin_user)
                db.session.commit()
                app.logger.info('超级管理员用户创建成功')
                
                # 创建测试用户（email字段可以为空）
                test_user = User(
                    username='test_user',
                    email=None  # email字段允许为空
                )
                # 对测试用户密码进行base64简单加密
                test_password = 'test_password'
                encoded_password = base64.b64encode(test_password.encode('utf-8')).decode('utf-8')
                test_user.password = encoded_password  # 使用base64编码后的密码
                test_user.roles.append(test_user_role)
                
                db.session.add(test_user)
                db.session.commit()
                app.logger.info('测试用户创建成功')
                
                app.logger.info('数据库初始化完成')
                
            except Exception as e:
                db.session.rollback()
                app.logger.error(f'数据库初始化失败: {str(e)}')
                raise
    else:
        app.logger.info('数据库文件已存在，跳过初始化')
